`timescale	1ps/1ps
module L9_com_ctrl_02(
		input	wire		resetb,
		input	wire		sclk,
		input	wire		comm_en,

		input	wire	[7:0]	current_depth,
                input	wire	[23:0]  local_net,
                input	wire		local_net_en,

		input	wire		rec_flag,
		input	wire		rec_error,
		input	wire	[7:0]	rec_data,
		
		input	wire		blank_flag,
		input	wire		redu_flag,
		input	wire		time_1ms_sync,
		
		input	wire		op_addr_mask,

		output	wire		spi2_cs,
		output	wire		spi2_clk,
		output	wire		spi2_mosi,

		//显示数据输出
		output	reg		artnet_flag,
		output	reg		dsout,
		output	reg	[7:0]	dout,
		output	reg		h_start,
		output	reg	[10:0]	h_num,
		output	wire		l2048_mode,
		
		output	wire	[7:0]	tout
		);

//************************************************/
//		!!设备类型!!
//************************************************/
parameter  SUB			=0;	   //分控
parameter  ASSIST		=1;	   //附属设备

parameter  DEVICE_TYPE		=SUB;

parameter  INITIAL_ADDR		=14'b0000_0000_1110_00;
parameter  TEST_ADDR		=14'b0000_0000_1110_01;
parameter  ACTIVE_ADDR		=14'b0000_0000_1110_10;

parameter  INITIAL_ERASE_ADDR	=INITIAL_ADDR+4;
parameter  TEST_ERASE_ADDR	=TEST_ADDR+4;
parameter  ACTIVE_ERASE_ADDR	=ACTIVE_ADDR+4;
//************************************************/
//		参数定义
//************************************************/
//************************************************/
parameter  Preamble_OFFSET	= 23 - 9;
parameter  PACK_TYPE_FIRST	= 24 - 9;
parameter  ASI_DEPTH_FIRST	= 26 - 9;
parameter  SUB_DEPTH_FIRST	= 28 - 9;
parameter  COM_PACK_SEL_TYPE	= 30 - 9;
parameter  COM_PACK_SUB_ADDR	= 31 - 9;
parameter  COM_PACK_ASI_ADDR	= 33 - 9;
parameter  COM_PACK_COMMAND	= 38 - 9;
parameter  COM_PACK_ADDR	= 40 - 9;
parameter  COM_PACK_HEAD_END	= 43 - 9;

parameter  TIMEOUT	        = 10;

//*************state******************************
parameter  IDLE_STATE		= 7'h01;
parameter  COM_RECEIVE		= 7'h02;
parameter  FPGA_RECEIVE		= 7'h04;
parameter  FPGA_SEND		= 7'h08;
parameter  SEND_FEEDBACK	= 7'h10;
parameter  ARTNET_PROC		= 7'h20;
parameter  ARTNET_SEND		= 7'h40;


///**************命令类型****************
parameter  MEM_READ		= 8'h08;
parameter  MEM_WRITE		= 8'h04;

//**********************************************/
//		信号定义
/************************************************/
reg	[10:0]	buf_addr_a,buf_addr_b;
reg		buf_wen_b;
reg	[7:0]	buf_wdata_b;
wire	[7:0]	buf_rdata_a;

reg	[6:0]	com_state;
wire		receive_flag;
reg		com_rec_temp;
reg		odd_flag;

reg	[7:0]	rec_d,rec_t;
wire	[15:0]	rec_16d,rec_16dl;

reg	[8:0]	rec_count;
reg		mac_flag,arp_flag,ipv4_flag,udp_flag,l9_port_flag,art_port_flag;
reg		v8_flag,l9_flag,iColor_flag;
reg		iColor_cmd_flag,icolor_mcu;
reg	[5:0]	iColor_h_count;
reg		art_flag,art_poll_flag,art_mcu,art_dmxdata_flag,artnet_command,artnet_ack_en;
reg		artnet_proc_end,artnet_send_end;
reg		mac_source_flag,ip_source_flag;
reg		madix_flag;

wire		cur_dev_type;
reg	[8:0]	icolor_count;
reg	[8:0]	depth_addr,device_addr;
reg		device_active,read_command,write_command,data_end;
reg	[23:0]	op_page_addr;
reg	[3:0]	op_ack_count;
reg		no_ack,fpga_send_end_flag,send_timeout;
reg	[3:0] 	ms_count;


reg	[8:0]	data_count;
reg		head_flag,head_end,com_packet_flag;
reg		rec_data_wen;

reg	[10:0]	art_proc_count;
reg	[15:0]	art_count;
reg	[8:0]	art_send_count,art_send_max;
reg	[1:0]	art_send_num;
reg		art_send_flag,send_flag_t,pre_flag_t;

reg		rec_flag_t;
reg		config_flag, config_wen;
reg	[3:0]	config_count;
reg	[7:0]	config_data;
reg		port_config_en;
 
reg		rec_buf_wen;
reg	[9:0]	rec_buf_waddr;
wire	[12:0]	rec_buf_raddr;
reg	[7:0]	rec_buf_wdata;
wire		rec_buf_rdata;

reg		send_flag_fpga, pre_flag_fpga;
reg	[7:0]	send_data_fpga;

//*************************************************/
//		通讯buf
//*************************************************/	
L9_swsr_1k8_tp_art_mif	com_buf(
	.clock_a ( sclk ),
	.address_a ( buf_addr_a ),
	.wren_a ( 1'h0 ),
	.data_a ( 8'h0 ),
	.q_a ( buf_rdata_a ),
	
	.clock_b ( sclk ),
	.address_b ( buf_addr_b ),
	//.wren_b ( buf_wen_b ),
	.wren_b ( 1'b0 ),
	.data_b ( buf_wdata_b ),
	.q_b ()
	);

L9_swsr_1kw8_8kr1_dp	rec_buf(
	.wrclock(sclk),
	.wren(rec_buf_wen),
	.wraddress(rec_buf_waddr),
	.data(rec_buf_wdata),
	
	.rdclock(sclk),
	.rdaddress(rec_buf_raddr),
	.q(rec_buf_rdata)
	);

//************************************************/
//		通讯包发送到MCU接口
//************************************************/
reg	[8:0]	rec_buf_count, send_spi_length;
reg	[18:0]	send_spi_count;
reg		rec_end, send_spi_start, rec_buf_w_sel, send_spi_flag, send_spi_last;
reg		send_spi_req, send_spi_en;

//***************接收控制***************
//接收写缓冲使能
always@(posedge sclk)
	rec_flag_t <= rec_flag;
		
//接收计数
always@(posedge sclk)
	if ((rec_flag == 0) && (rec_flag_t == 0))
		rec_buf_count <= 8;		//保留8个字节的包头
	else if ((rec_flag == 1) && (rec_buf_count[8:6] != 3'b111))
		rec_buf_count <= rec_buf_count + 1;
		
//接收结束标志
always@( * )
	 if ((rec_flag == 0 && rec_flag_t == 1))
		rec_end <= 1;
	else
		rec_end <= 0;
		
//***************转发控制***************
//上一包未转发完成，不能发送新包
always @( * )
	send_spi_en = ~send_spi_flag;

//转发使能
always@(posedge sclk)
	if ((art_mcu == 1) || (arp_flag == 1) || (icolor_mcu == 1))
		send_spi_req <= 1;
	else
		send_spi_req <= 0;

//SPI转发开始
always@(posedge sclk)
	if ((comm_en == 1) && (rec_end == 1) && (send_spi_req == 1) && (send_spi_en == 1))
		send_spi_start <= 1;
	else
		send_spi_start <= 0;

//切换地址区
always@(posedge sclk or negedge resetb)
	if (resetb == 0)
		rec_buf_w_sel <= 0;
	else if (send_spi_start == 1)
		rec_buf_w_sel <= ~rec_buf_w_sel;

//保存转发长度
always@(posedge sclk or negedge resetb)
	if (resetb == 0)
		send_spi_length <= 0;
	else if (send_spi_start == 1)
		send_spi_length <= rec_buf_count;

//SPI转发使能
always@(posedge sclk or negedge resetb)
	if (resetb == 0)
		send_spi_flag <= 0;
	else if (send_spi_start == 1)
		send_spi_flag <= 1;
	else if (send_spi_last == 1)
		send_spi_flag <= 0;

//SPI转发计数
always@(posedge sclk)
	if (send_spi_flag == 0)
		send_spi_count <= 0;
	else
		send_spi_count <= send_spi_count + 1;

//SPI转发结束
always@(posedge sclk)
	if ((send_spi_flag == 1) && (send_spi_count[18:10] == send_spi_length))
		send_spi_last <= 1;
	else
		send_spi_last <= 0;

//***************配置控制***************
//配置使能
always@(posedge sclk or negedge resetb)
	if (resetb == 0)
		config_flag <= 0;
	else if (send_spi_start == 1)
		config_flag <= 1;
	else if (config_count[3] == 1)
		config_flag <= 0;

//配置计数
always@(posedge sclk)
	if (config_flag == 0)
		config_count <= 0;
	else
		config_count <= config_count + 1;

//配置使能
always@(posedge sclk)
	if (config_flag == 0)
		config_wen <= 0;
	else if (config_count == (2 - 1))
		config_wen <= 1;
	else
		config_wen <= 0;

//配置数据
always@(posedge sclk)
	if (config_flag == 0)
		config_data <= 0;
	else if (config_count == (2 - 1))
		config_data <= current_depth;
	else
		config_data <= 0;

//***************缓冲控制***************
always@(posedge sclk)
	if ((rec_flag == 1) || (config_wen == 1))
		rec_buf_wen <= 1;
	else
		rec_buf_wen <= 0;

always@(posedge sclk)
	if (rec_flag == 1)
		rec_buf_wdata <= rec_data;
	else if (config_wen == 1)
		rec_buf_wdata <= config_data;
	else
		rec_buf_wdata <= 0;
	
always@(posedge sclk)
	if (rec_flag == 1)
		rec_buf_waddr <= {rec_buf_w_sel, rec_buf_count[8:0]};
	else if (config_wen == 1)
		rec_buf_waddr <= {~rec_buf_w_sel, 5'h0, config_count[3:0]};
	else
		rec_buf_waddr <= 0;

assign	rec_buf_raddr = {~rec_buf_w_sel, send_spi_count[18:7]};

//***************输出给MCU的信号***************
assign	spi2_cs = ~send_spi_flag;
assign	spi2_clk = send_spi_count[6];
assign	spi2_mosi = rec_buf_rdata;

//************************************************/
//		状态控制
//************************************************/
//**************主状态机*******************
always@(posedge sclk or negedge resetb)
	if(resetb == 0)
		com_state <= IDLE_STATE;
	else 
		case(com_state)
			IDLE_STATE:	
				if (comm_en == 1 && rec_flag == 1)
					com_state <= COM_RECEIVE;	

			COM_RECEIVE:
				if (rec_flag == 0) begin
					if (rec_error == 1)
						com_state <= IDLE_STATE;
					else if (write_command == 1)
						com_state <= FPGA_RECEIVE;
					else if (read_command == 1)
						com_state <= FPGA_SEND;
					else if (artnet_command==1)
						com_state <= ARTNET_PROC;
					else
						com_state <= IDLE_STATE;
					end
					
			FPGA_RECEIVE:
				//if(fpga_rec_end == 1 || no_ack == 1)
					com_state <= IDLE_STATE;
							
			FPGA_SEND:
				//if(fpga_send_end_flag==1 || no_ack == 1)
				//begin
				//	if(redu_flag==0)	//单向级联模式
				//		com_state <= SEND_FEEDBACK;
				//	else if(blank_flag==1 || send_timeout==1)	//双口冗余模式，等空闲包
						com_state <= SEND_FEEDBACK;
				//end
				
			SEND_FEEDBACK:
				//if(data_end == 1)
					com_state <= IDLE_STATE;
							
			ARTNET_PROC:
				if(artnet_proc_end == 1)
				begin
					if (artnet_ack_en == 1)
						com_state <= ARTNET_SEND;
					else
						com_state <= IDLE_STATE;
				end			
			ARTNET_SEND:
				if(artnet_send_end == 1)
					com_state <= IDLE_STATE;
							
			default:	com_state <= IDLE_STATE;
		endcase

always@(posedge sclk or negedge resetb)
	if(resetb == 0)
		odd_flag <= 1;
	else if (com_state == COM_RECEIVE && rec_flag == 0 && art_port_flag == 1)
		odd_flag <= ~odd_flag;

//**************通讯包接收类型判断*******************
//接收标志
assign	receive_flag = com_state[1];

always	@(posedge sclk) begin
	rec_d <= rec_data;
	rec_t <= rec_d;
	end

assign	rec_16d = {rec_t,rec_d};
assign	rec_16dl = {rec_d,rec_t};

//数据计数
always	@(posedge sclk)
	if (receive_flag == 0)
		rec_count <= 0;
	else if (rec_count[8] == 0)
		rec_count <= rec_count + 1;

//V8包类型判断
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		mac_flag <= 0;
	else if (rec_count == (22 - 9) && rec_16d == 16'h55AA)
		mac_flag <= 1;

//ipv4包类型判断
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		ipv4_flag <= 0;
	else if (rec_count == (22 - 9) && rec_16d == 16'h0800)
		ipv4_flag <= 1;

//ipv4包类型判断
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		arp_flag <= 0;
	else if (rec_count == (22 - 9) && rec_16d == 16'h0806)
		arp_flag <= 1;

//UDP包类型判断
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		udp_flag <= 0;
	else if (ipv4_flag == 1 && rec_count == (32 - 9) && rec_d == 8'h11)
		udp_flag <= 1;

//L9端口判断
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		l9_port_flag <= 0;
	else if (udp_flag == 1 && rec_count == (46 - 9) && rec_16d == 16'h55AA)
		l9_port_flag <= 1;

//ArtNet端口判断
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		art_port_flag <= 0;
	else if (udp_flag == 1 && rec_count == (46 - 9) && rec_16d == 16'h1936)
		art_port_flag <= 1;

//V8包标志
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		v8_flag <= 0;
	else if (mac_flag == 1 && rec_count == (23 - 9) && rec_d == 8'h81)
		v8_flag <= 1;
			
//L9包标志
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		l9_flag <= 0;
	else if (l9_port_flag == 1 && rec_count == (51 - 9) && rec_d == 8'h81)
		l9_flag <= 1;
			
//智彩协议标志
always	@( * )
	if (v8_flag == 1 || l9_flag == 1)
		iColor_flag <= 1;
	else
		iColor_flag <= 0;

//智彩包头计数
always	@(posedge sclk)
	if (iColor_flag == 0)
		iColor_h_count <= 0;
	else if (iColor_h_count[5] == 0)
		iColor_h_count <= iColor_h_count + 1;

//智彩命令标志
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		iColor_cmd_flag <= 0;
	else if ((iColor_flag == 1) && (iColor_h_count == (52 - 51 - 1)) && (rec_d == 8'hC5))
		iColor_cmd_flag <= 1;

//ArtNet包标志
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		art_flag <= 0;
	else if (art_port_flag == 1 && rec_count == (51 - 9) && rec_d == "A")
		art_flag <= 1;
		
//Madix包标志
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		madix_flag <= 0;
	else if (art_port_flag == 1 && rec_count == (51 - 9) && rec_d == "M")
		madix_flag <= 1;
		
//iColor 通讯命令包提取
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		icolor_mcu <= 0;
	else if (iColor_cmd_flag == 1 && op_addr_mask == 1)
		icolor_mcu <= 1;
	else
		icolor_mcu <= 0;

//ArtNet包类型提取
always	@(posedge sclk)
	if (com_state == IDLE_STATE) begin
		art_poll_flag <= 0;
		art_dmxdata_flag <= 0;
		art_mcu <= 0;
		end
	else if (art_flag == 1 && rec_count == (60 - 9))
		case(rec_16dl)
			16'h2000:	art_mcu <= 1;//art_poll_flag <= 1;
			16'h8000:	art_mcu <= 1;
			16'h8200:	art_mcu <= 1;
			16'h8300:	art_mcu <= 1;
			16'h5000:	art_dmxdata_flag <= 1;
		endcase		

//处理ART_NET标志
always	@(posedge sclk)
	artnet_command = art_poll_flag | art_dmxdata_flag;
	
//反馈ART_NET标志
always	@(posedge sclk)
	artnet_ack_en = art_poll_flag;

//源Mac
always	@(posedge sclk)
	if (rec_count >= (14 - 8 - 1) && rec_count < (20 - 8 -1))
		mac_source_flag <= 1;
	else
		mac_source_flag <= 0;
		
//源IP
always	@(posedge sclk)
	if ((udp_flag == 1) && rec_count >= (34 - 8 - 1) && rec_count < (38 - 8 -1))
		ip_source_flag <= 1;
	else
		ip_source_flag <= 0;
		
//**********************************************************************/
//		显示数据提取
//**********************************************************************/
reg	[14:0]	dmx_port_num;
reg		dmx_port_local, h_temp;
reg	[7:0]	port_base;

always	@(posedge sclk)
	port_base = current_depth - 1;
	
//行号提取
always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		dmx_port_num <= 0;
	else if (art_dmxdata_flag == 1 && rec_count == (66 - 9))
		dmx_port_num <= rec_16dl;

always	@(posedge sclk)
	artnet_flag <= artnet_command;
//	if (com_state == IDLE_STATE)
//		vsout <= 0;
//	else if (art_dmxdata_flag == 1 && rec_count == (66 - 9) && rec_16dl == 0)
//		vsout <= 1;
//	else if (rec_count == (68 - 9))
//		vsout <= 0;

always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		dmx_port_local <= 0;
	else if (art_dmxdata_flag == 1 && rec_count == (67 - 9) && dmx_port_num [14:3] == port_base)
		dmx_port_local <= 1;

always	@(posedge sclk)
	if (com_state == IDLE_STATE)
		h_num <= 0;
	else if (art_dmxdata_flag == 1 && rec_count == (65 - 9))
		h_num <= rec_d[2:0];

always	@(posedge sclk)
	if (dmx_port_local == 1 && rec_count == (69 - 9))
		h_temp <= 1;
	else if (receive_flag == 0)
		h_temp <= 0;

always	@(posedge sclk)
	if (dmx_port_local == 1 && rec_count == (70 - 9))
		h_start <= 1;
	else
		h_start <= 0;

always	@(posedge sclk)
	dsout <= h_temp;
	
always	@(posedge sclk)
	if (h_temp == 1)
		dout <= rec_t;
	else
		dout <= 0;

assign	l2048_mode = 0;
		
//**********************************************************************/
//		内部BUF控制
//**********************************************************************/
//*****************写控制*****************
always	@*
	buf_wen_b <= mac_source_flag | ip_source_flag;
	//buf_wen_b <= 1'b0;
				
always	@*
	if (mac_source_flag == 1)
		buf_addr_b <= rec_count + (8 - 6);
	else
		buf_addr_b <= rec_count + (8 + 4);
        
always	@*
        buf_wdata_b <= rec_d;

//*****************读控制*****************
always	@*
	//if (art_send_count[8:6] == 0)
	//	buf_addr_a <= {1'b0,art_send_count[8:0]};
	//else
	//	buf_addr_a <= {odd_flag, art_send_count[9:0]};
		buf_addr_a <= {1'b0, art_count[14], art_send_count[8:0]};
						
//************************************************/
//		通讯包参数提取
//************************************************/
reg	[47:0]	remote_mac, remote_mac_shift;
reg	[31:0]	remote_ip, local_ip, remote_ip_shift, local_ip_shift;
wire	[7:0]	local_mac_l;
reg	[31:0]	check_ip_adjust, check_ip_sum;
reg	[31:0]	check_port_adjust;
reg	[31:0]	check_udp_adjust, check_1_sum, check_2_sum;
reg	[16:0]	check_ip_sum_a, check_1_sum_a, check_2_sum_a;
reg	[15:0]	check_ip, check_1_udp, check_2_udp;
reg		remote_mac_out, remote_ip_out, local_mac_l_out, local_ip_out, dmx_port_out, check_data_out;
reg	[7:0]	port_data, check_data;

//主机MAC
always	@(negedge resetb or posedge sclk)
	if (resetb == 0)
		remote_mac <= 48'h0;
	else if (receive_flag == 1) begin
		case (rec_count)
			9'h006:	remote_mac[47:40] <= rec_d;
			9'h007:	remote_mac[39:32] <= rec_d;
			9'h008:	remote_mac[31:24] <= rec_d;
			9'h009:	remote_mac[23:16] <= rec_d;
			9'h00A:	remote_mac[15:8] <= rec_d;
			9'h00B:	remote_mac[7:0] <= rec_d;
		endcase
	end

//主机IP
always	@(negedge resetb or posedge sclk)
	if (resetb == 0)
		remote_ip <= 32'h0;
	else if (receive_flag == 1) begin
		case (rec_count)
			9'h01A:	remote_ip[31:24] <= rec_d;
			9'h01B:	remote_ip[23:16] <= rec_d;
			9'h01C:	remote_ip[15:8] <= rec_d;
			9'h01D:	remote_ip[7:0] <= rec_d;
		endcase
	end

//本地MAC低位
assign	local_mac_l = {1'b1, current_depth[6:0]};
//assign	local_mac_l = 8'h10;

//本地IP
always	@(posedge sclk)
	if (local_net_en == 0)
		local_ip <= {24'hC0A801, local_mac_l};
	else
		local_ip <= {local_net, local_mac_l};

//IP包头校验调整
always	@(posedge sclk)
	check_ip_adjust <= remote_ip[31:16] + remote_ip[15:0] + local_ip[31:16] + local_ip[15:0];

//IP包头校验
always	@(posedge sclk)
	check_ip_sum <= 16'h8620 + check_ip_adjust;

always	@(posedge sclk)
	check_ip_sum_a <= check_ip_sum[31:16] + check_ip_sum[15:0];

always	@(posedge sclk)
	check_ip <= check_ip_sum_a[16] + check_ip_sum_a[15:0];

//UDP包头校验调整-端口地址调整
always	@(posedge sclk)
	check_port_adjust <= {5'h0, port_base[7:5], 4'h0, port_base[4:1]} + {3'h0, port_base[0], 4'h0, 3'h0, port_base[0], 4'h0};
	
//UDP包头校验调整
always	@(posedge sclk)
	check_udp_adjust <= check_port_adjust + check_ip_adjust + local_ip[31:16] + local_ip[15:0] + {local_mac_l[7:0], local_ip[31:24]} + local_ip[23:8] + {local_ip[7:0], 8'h0};
	
//UDP包头校验-设备1
always	@(posedge sclk)
	check_1_sum <= 32'h000CCABE + check_udp_adjust[19:0];
	
always	@(posedge sclk)
	check_1_sum_a <= check_1_sum[31:16] + check_1_sum[15:0];

always	@(posedge sclk)
	check_1_udp <= check_1_sum_a[16] + check_1_sum_a[15:0];

//UDP包头校验-设备2
always	@(posedge sclk)
	check_2_sum <= 32'h000CDCD3 + check_udp_adjust[19:0];

always	@(posedge sclk)
	check_2_sum_a <= check_2_sum[31:16] + check_2_sum[15:0];

always	@(posedge sclk)
	check_2_udp <= check_2_sum_a[16] + check_2_sum_a[15:0];

//************************************************/
//		ART-NET数据处理
//************************************************/
always	@(posedge sclk)
	if(com_state != ARTNET_PROC)
		art_proc_count <= 0;
	else
		art_proc_count <= art_proc_count + 1;

always	@(posedge sclk)
	if (art_poll_flag == 1)
		artnet_proc_end <= art_proc_count[8];
	else if (art_dmxdata_flag == 1)
		artnet_proc_end <= art_proc_count[5];
	else
		artnet_proc_end <= 1;

//************************************************/
//		ART-NET数据反馈
//************************************************/
//art_net反馈计数
always	@(posedge sclk)
	if(com_state != ARTNET_SEND)
		art_count <= 0;
	else
		art_count <= art_count + 1;

//发送次数和长度控制
always	@(posedge sclk)
	if (art_poll_flag == 1) begin
		art_send_num <= 1;
		art_send_max <= 9'h1F0;
		end		
	else begin
		art_send_num <= 0;
		art_send_max <= 0;
		end

//发送结束
always	@(posedge sclk)
	if (com_state == ARTNET_SEND && art_count[15:14] >= art_send_num && art_send_count >= art_send_max)
		artnet_send_end <= 1;
	else
		artnet_send_end <= 0;

//每16384个clk，预留1个长度小于512的反馈包
always	@(posedge sclk)
	if(com_state != ARTNET_SEND)
		art_send_flag <= 0;
	else if (art_count[13:9] == 0)
		art_send_flag <= 1;
	else
		art_send_flag <= 0;

always	@(posedge sclk)
	if(art_send_flag == 0)
		art_send_count <= 0;
	else
		art_send_count <= art_send_count + 1;

//前导标志
always	@(posedge sclk)
	if((art_send_flag == 1) && (art_send_count[8:3] == 7'h00))
		pre_flag_t <= 1;
	else
		pre_flag_t <= 0;

//发送标志
always	@(posedge sclk)
	if((art_send_flag == 1) && (art_send_count[8:0] < 288))
		send_flag_t <= 1;
	else
		send_flag_t <= 0;
		
//标志信号输出
always	@(posedge sclk) begin
	send_flag_fpga <= send_flag_t;
	pre_flag_fpga <= pre_flag_t;
	end

//************************************************/
//		ART-NET数据处理
//************************************************/
//主机MAC输出标志
always	@(posedge sclk)
	if ((art_send_count[8:0] >=8) && (art_send_count[8:0] < 14))
		remote_mac_out <= 1;
	else
		remote_mac_out <= 0;
	
//主机MAC地址输出
always	@(posedge sclk)
	if (remote_mac_out == 0)
		remote_mac_shift <= remote_mac;
	else
		remote_mac_shift <= {remote_mac_shift[39:0], remote_mac_shift[47:40]};
		
//本地MAC低位输出标志
always	@(posedge sclk)
	if ((art_send_count[8:0] == 19) || (art_send_count[8:0] == 256))
		local_mac_l_out <= 1;
	else
		local_mac_l_out <= 0;

//主机IP输出标志
always	@(posedge sclk)
	if ((art_send_count[8:0] >=38) && (art_send_count[8:0] < 42))
		remote_ip_out <= 1;
	else
		remote_ip_out <= 0;
	
//主机IP地址输出
always	@(posedge sclk)
	if (remote_ip_out == 0)
		remote_ip_shift <= remote_ip;
	else
		remote_ip_shift <= {remote_ip_shift[23:0], remote_ip_shift[31:24]};
		
//本地IP输出标志
always	@(posedge sclk)
	if ((art_send_count[8:0] >= 34) && (art_send_count[8:0] < 38))
		local_ip_out <= 1;
	else if ((art_send_count[8:0] >= 60) && (art_send_count[8:0] < 64))
		local_ip_out <= 1;
	else if ((art_send_count[8:0] >= 257) && (art_send_count[8:0] < 261))
		local_ip_out <= 1;
	else
		local_ip_out <= 0;
	
//本地IP地址输出
always	@(posedge sclk)
	if (local_ip_out == 0)
		local_ip_shift <= local_ip;
	else
		local_ip_shift <= {local_ip_shift[23:0], local_ip_shift[31:24]};

//端口输出标志
always	@(posedge sclk)
	if (art_send_count[8:0] >= 240 && art_send_count[8:0] < 244)
		dmx_port_out <= 1;
	else if (art_send_count[8:0] == 68 || art_send_count[8:0] == 69)
		dmx_port_out <= 1;
	else
		dmx_port_out <= 0;

		
//端口数据输出
always	@(posedge sclk)
	if (art_send_count[8:0] >= 240 && art_send_count[8:0] < 244)
		port_data <= {4'h0, port_base[0], art_count[14], art_send_count[1:0]};
	else if (art_send_count[8:0] == 68)
		port_data <= port_base[7:5];
	else if (art_send_count[8:0] == 69)
		port_data <= port_base[4:1];
	else
		port_data <= 0;

//校验数据输出标志
always	@(posedge sclk)
	if (art_send_count[8:0] == 32 || art_send_count[8:0] == 33)
		check_data_out <= 1;
	else if (art_send_count[8:0] == 48 || art_send_count[8:0] == 49)
		check_data_out <= 1;
	else
		check_data_out <= 0;
		
//校验数据输出
always	@(posedge sclk)
	if (art_send_count[8:0] == 32)
		check_data <= check_ip[15:8];
	else if (art_send_count[8:0] == 33)
		check_data <= check_ip[7:0];
	else if (art_send_count[8:0] == 48) begin
		if (art_count[14] == 1'b0)
			check_data <= check_1_udp[15:8];
		else
			check_data <= check_2_udp[15:8];
		end
	else if (art_send_count[8:0] == 49) begin
		if (art_count[14] == 1'b0)
			check_data <= check_1_udp[7:0];
		else
			check_data <= check_2_udp[7:0];
		end
	else
		check_data <= 0;
		
//数据输出
always	@(posedge sclk)
	if (remote_mac_out == 1)
		send_data_fpga <= remote_mac_shift[47:40];
	else if (remote_ip_out == 1)
		send_data_fpga <= remote_ip_shift[31:24];
	else if (local_mac_l_out == 1)
		send_data_fpga <= local_mac_l;
	else if (local_ip_out == 1)
		send_data_fpga <= local_ip_shift[31:24];
	else if (dmx_port_out == 1)
		send_data_fpga <= port_data;
	else if (check_data_out == 1)
		send_data_fpga <= ~check_data;
	else if (send_flag_t == 1)
		send_data_fpga <= buf_rdata_a;
	else
		send_data_fpga <= 0;

/************************************************/
//		测试信号
/************************************************/
assign	tout = {arp_flag, comm_en, ipv4_flag, l9_flag, art_dmxdata_flag, send_spi_req, send_spi_en};

endmodule		
